refresh zaznamov nad IBQuery

Otázka od: hlas

18. 8. 2004 6:29

Na jednom formulari mam grid a komponenty
TIBQuery a TIBUpdatesql. Tieto pouzivam iba na zobrazenie
FB tabulky.
Na druhom formulari robim pomozou edit boxov a TIBSQL
zapisy do tabulky.

Po update uz existujuceho zaznamu na druhom formulari dokazem pekne refreshnut
zaznam v gride na prvom formulari. Robim to tak, ze do komponenty TIBUpdateSQL
vlozim RefreshSQL:
'select * from tabulka where pole=:old_pole. (pole je prim.key)
a zavolam TIBQuery. refresh. Toto mi pekne obnovi-refreshne prave editovany
zaznam v gride.
Avsak problem mam ak chcem refreshnut grid po INSERTE alebo DELETE.
Ak na druhom formulari urobim insert tak do komponenty
TIBUpdateSQL vlozim vlastnost refresql: 'select
* from tabulka
where pole=novyprimkluc'. a zavolam TIBQuery.refresh.
Toto mi sice obnovi zaznam v gride ale tak ze novy zaznam prekryje ten, ktory bol
predtym aktualny. Teda v gride mi nepribudne o jeden zaznam viac, ako by malo,
ale ten ktory bol pred INSERTOM aktualny sa ako keby
prepise tym novym. Je to len vec zobrazenia gridu, lebo ked dam close a open
tak je vsetko ok.
Myslim ze robit TIBQuery.close a TIBQuery.open po kazdom novom zazname
moze dost zdrzovat.
Ako vykonat refresh TIBQuery po inserte - po pridani noveho zaznamu,
tak aby som refreshoval iba jeden - ten novy zaznam a nie celu tabulku?
A co urobit po delete, aby zmizol z gridu jeden zaznam a nebolo
treba robit close a open?


Odpovedá: David Fajfr

18. 8. 2004 8:59

> Myslim ze robit TIBQuery.close a TIBQuery.open po kazdom novom zazname
> moze dost zdrzovat.
> Ako vykonat refresh TIBQuery po inserte - po pridani noveho zaznamu,
> tak aby som refreshoval iba jeden - ten novy zaznam a nie celu tabulku?
> A co urobit po delete, aby zmizol z gridu jeden zaznam a nebolo
> treba robit close a open?

Ahoj,

Ja to delam jednoduse tak, ze po zapisu poslu ciselniku, ktery mi ten
editacni form vyvolal, zpravu ze nastala zmena dat. Delam to pres
PostMessage, kde v parametru poslu typ zapisu (Insert, Update) a ID zaznamu
ktery se zmenil nebo pridal. Ten ciselnik, ktery dostane tuto zpravu si onen
zaznam otevre v jinem Query a provede pozadovanou akci ve svem datasetu -
Pri update se provede Locate a prirazeni hodnot; Pri insertu se provede
Append a pak prirazeni hodnot. S vymazanim zaznamu je to podobne. Jen je
potreba nemit dataset v ciselniku ReadOnly a provadene "nahledove" operace
nepromitat do databaze.

Poslani zpravy ma i tu vyhodu, ze vsechny okna v aplikaci jsou na sobe
nezavisle... Treba muze nastat situace, ze uzivatel otevre ciselnik, z
ciselniku editacni form a ciselnik zavre... potom, kdyz editaci zapisuje,
jen se posle message s handle jiz neexistujiciho okna a vse je OK.

David



Odpovedá: hlas

18. 8. 2004 9:28

Ak som to spravne pochopil tak po tom inserte z
druheho formulara mam ten grid na prvom formulari
napojit na iny datasource a iny ibquery. Na tomto
ibquery urobit append a priradit hodnoty a post?
a potom zasa pripojit grid na povodny datasource
a povodny ibquery? Takto?



----- Original Message -----
From: "David Fajfr"
> Ja to delam jednoduse tak, ze po zapisu poslu ciselniku, ktery mi ten
> editacni form vyvolal, zpravu ze nastala zmena dat. Delam to pres
> PostMessage, kde v parametru poslu typ zapisu (Insert, Update) a ID
zaznamu
> ktery se zmenil nebo pridal. Ten ciselnik, ktery dostane tuto zpravu si
onen
> zaznam otevre v jinem Query a provede pozadovanou akci ve svem datasetu -
> Pri update se provede Locate a prirazeni hodnot; Pri insertu se provede
> Append a pak prirazeni hodnot. S vymazanim zaznamu je to podobne. Jen je
> potreba nemit dataset v ciselniku ReadOnly a provadene "nahledove" operace
> nepromitat do databaze.
>
> Poslani zpravy ma i tu vyhodu, ze vsechny okna v aplikaci jsou na sobe
> nezavisle... Treba muze nastat situace, ze uzivatel otevre ciselnik, z
> ciselniku editacni form a ciselnik zavre... potom, kdyz editaci zapisuje,
> jen se posle message s handle jiz neexistujiciho okna a vse je OK.
>
> David


Odpovedá: David Fajfr

18. 8. 2004 10:04



> Ak som to spravne pochopil tak po tom inserte z
> druheho formulara mam ten grid na prvom formulari
> napojit na iny datasource a iny ibquery. Na tomto
> ibquery urobit append a priradit hodnoty a post?
> a potom zasa pripojit grid na povodny datasource
> a povodny ibquery? Takto?


Ne ne, uplne jinak..

1) mas form, ktery ma IBQuery1 a grid, ktery obsahuje nejaka data
2) form prijme zpravu, ze se zmenil/pridal zaznam s ID = 999
3) v IBQuery2 si udelas Select * from tabulka where ID = 999

Takze v IBQuery2 mas cerstve hodnoty zaznamu a ted uz je jen vhodnym
zpusobem nacpes do IBQuery1, ktery je napojeny na grid.

4a) - pokud se provedl Insert - vis ze zpravy
   IBQuery1.Append;
   Predat hodnoty(IBQuery2, IBQuery1);
   IBQuery1.Post;

4b) - pokud se provedl Update
   if IBQuery1.Locate('ID', 999, []) then begin
      IBQuery1.Edit;
      Predat hodnoty(IBQuery2, IBQuery1);
      IBQuery1.Post;
   end;

4c) - pokud se provedl Delete
   if IBQuery1.Locate('ID', 999, []) then
      IBQuery1.Delete;

procedure PredatHodnoty(Data2, Data1: TDataSet);
var
   i: integer;
   FieldName: string;
begin
   for i := 0 to Data1.FieldCount - 1 do begin
      FieldName := Data1.Fields[i].FieldName;
      if Data2.FindField(FieldName) <> nil then
         Data1.Fields[i].AsVariant :=
Data2.FieldByName(FieldName).AsVariant;
   end;
end;

Snad jsem to napsal pochopitelne  
Treba existuje i lepsi zpusob, ale vymyslel jsem pouze tento, ale musim
rict, ze je to celkem rychle a spolehlive...

David


Odpovedá: hlas

20. 8. 2004 6:33

Tak som to vyskusal ale mam tam nejaky problem.
pri IBquery1.post mi to hlasi chybu primarneho kluca.
ako keby si to checklo, ze v databaze uz tento PK
existuje a ohlasi mi chybu, ale potom mi pekne
zobrazi grid tak ako som chcel.
Tak neviem preco ta hlaska. Hrozne mi uz
vadia tie appendy a posty. nikdy pri tom clovek
nevie co sa tam v skutocnosti deje.
 
inak dik, ak toto vyriesim tak mi to pomohlo.
ale ten moj sposob pri update sa miz zda jednoduchsi.
takze inserty a delety by som robil podla teba.

a tiez som musel zmenit transakciu na tom prvom query.
ta transakcia bola read, lebo som nepredpokladal, ze tam
budem zapisovat.



----- Original Message -----
From: "David Fajfr"
> Ne ne, uplne jinak..
>
> 1) mas form, ktery ma IBQuery1 a grid, ktery obsahuje nejaka data
> 2) form prijme zpravu, ze se zmenil/pridal zaznam s ID = 999
> 3) v IBQuery2 si udelas Select * from tabulka where ID = 999
>
> Takze v IBQuery2 mas cerstve hodnoty zaznamu a ted uz je jen vhodnym
> zpusobem nacpes do IBQuery1, ktery je napojeny na grid.
>
> 4a) - pokud se provedl Insert - vis ze zpravy
> IBQuery1.Append;
> Predat hodnoty(IBQuery2, IBQuery1);
> IBQuery1.Post;
>
> 4b) - pokud se provedl Update
> if IBQuery1.Locate('ID', 999, []) then begin
> IBQuery1.Edit;
> Predat hodnoty(IBQuery2, IBQuery1);
> IBQuery1.Post;
> end;
>
> 4c) - pokud se provedl Delete
> if IBQuery1.Locate('ID', 999, []) then
> IBQuery1.Delete;
>
> procedure PredatHodnoty(Data2, Data1: TDataSet);
> var
> i: integer;
> FieldName: string;
> begin
> for i := 0 to Data1.FieldCount - 1 do begin
> FieldName := Data1.Fields[i].FieldName;
> if Data2.FindField(FieldName) <> nil then
> Data1.Fields[i].AsVariant :=
> Data2.FieldByName(FieldName).AsVariant;
> end;
> end;
>
> Snad jsem to napsal pochopitelne  
> Treba existuje i lepsi zpusob, ale vymyslel jsem pouze tento, ale musim
> rict, ze je to celkem rychle a spolehlive...
>
> David
>



Odpovedá: hlas

20. 8. 2004 7:03

Je mi to jasne, ten post zapisuje rovno aj
do databazovej tabulky a preto ta hlaska.
Ty si to tam pisal, ze "nepromitat nahledove operace
do databaze". Ako si to
myslel?
Napada ma osetrit to cez try except
alebo na tibquery nastavit cachedupdates na true.
Ako to robis aby post zapisal len do gridu a nie do
databazovej tabulky?


----- Original Message -----

> Tak som to vyskusal ale mam tam nejaky problem.
> pri IBquery1.post mi to hlasi chybu primarneho kluca.
> ako keby si to checklo, ze v databaze uz tento PK
> existuje a ohlasi mi chybu, ale potom mi pekne
> zobrazi grid tak ako som chcel.
> Tak neviem preco ta hlaska. Hrozne mi uz
> vadia tie appendy a posty. nikdy pri tom clovek
> nevie co sa tam v skutocnosti deje.
>
> inak dik, ak toto vyriesim tak mi to pomohlo.
> ale ten moj sposob pri update sa miz zda jednoduchsi.
> takze inserty a delety by som robil podla teba.
>
> a tiez som musel zmenit transakciu na tom prvom query.
> ta transakcia bola read, lebo som nepredpokladal, ze tam
> budem zapisovat.
>


Odpovedá: David Fajfr

20. 8. 2004 8:15

> inak dik, ak toto vyriesim tak mi to pomohlo.
> ale ten moj sposob pri update sa miz zda jednoduchsi.
> takze inserty a delety by som robil podla teba.

Nevim jak mas postavenou aplikaci, zda treba nevolas editacni formy
modalne... Ale ja mam vsechny formy nezavisle na sobe a proto muze nastat
situace, kdy uzivatel otevre ciselnik, otevre zaznam pro editaci, vrati se
na ciselnik, odjede s kurzorem na jiny radek, pak se vrati do editace a
zapise... co se ti refreshne? Proto ten slozitejsi zpusob i na update.


> Je mi to jasne, ten post zapisuje rovno aj
> do databazovej tabulky a preto ta hlaska.
> Ty si to tam pisal, ze "nepromitat nahledove operace
> do databaze". Ako si
to myslel?
> Napada ma osetrit to cez try except
> alebo na tibquery nastavit cachedupdates na true.
> Ako to robis aby post zapisal len do gridu a nie do
> databazovej tabulky?

Nepouzivam IBQuery + IBUpdate, ale IBDataSet... ale bude to stejne.
Komponenty se chovaji ReadOnly, dokud do InsertSQL, UpdateSQL nebo DeleteSQL
nedas nejaky korektni SQL prikaz. Proto jsem tam hodil jen neco, co ti
stejne zmeny v DB delat nebude.
Napr. "Update table set ID=ID where ID = -1"
Taky si dej pozor, abys nemel Fieldy nastavene na ReadOnly.
CachedUpdates := True je taky dobre a nedelat ApplyUpdates + Commit

Hodne zdaru  


David Liska, TH SOFT